#region Copyright

// The contents of this file are subject to the Mozilla Public License
//  Version 1.1 (the "License"); you may not use this file except in compliance
//  with the License. You may obtain a copy of the License at
//  
//  http://www.mozilla.org/MPL/
//  
//  Software distributed under the License is distributed on an "AS IS"
//  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
//  License for the specific language governing rights and limitations under 
//  the License.
//  
//  The Initial Developer of the Original Code is Robert Smyth.
//  Portions created by Robert Smyth are Copyright (C) 2008.
//  
//  All Rights Reserved.

#endregion

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using NUnitGridThreadRunner.Alchemi;


namespace NUnit.Extensions.NUnitGridRunner
{
    public class RunnerNames
    {
        private readonly Dictionary<string, string> nameMap = new Dictionary<string, string>();
        private readonly string nameMappingFile;
        private XmlDocument xmlDocument;

        public RunnerNames(TargetFileSystem environment)
        {
            nameMappingFile = Path.Combine(environment.GetRunnerDataFolder(), "ComputerNames.xml");
        }

        private void LoadMapFile()
        {
            if (File.Exists(nameMappingFile))
            {
                string xmlText;
                using (var streamReader = new StreamReader(nameMappingFile))
                {
                    xmlText = streamReader.ReadToEnd();
                }

                xmlDocument = new XmlDocument();
                try
                {
                    xmlDocument.LoadXml(xmlText);
                    XmlNodeList nameNodes = xmlDocument.SelectNodes("/NUnitGridRunner/Computers/Computer");

                    foreach (XmlNode computerNode in nameNodes)
                    {
                        XmlNode nameNode = computerNode["Name"];
                        XmlNode nickNameNode = computerNode["NickName"];
                        nameMap.Add(nameNode.InnerText, nickNameNode.InnerText);
                    }
                }
                catch (Exception exception)
                {
                    Console.Error.WriteLine("Error reading '{0}'. Possibly corrupt.\nException {1}", nameMappingFile,
                                            exception.Message);
                }
            }
        }

        public string MapName(string computerName)
        {
            if (xmlDocument == null)
            {
                LoadMapFile();
            }

            computerName = computerName.ToUpper();

            string nickName;
            if (nameMap.ContainsKey(computerName))
            {
                nickName = nameMap[computerName];
            }
            else
            {
                nickName = computerName;
                nameMap.Add(computerName, nickName);
            }

            return nickName;
        }

        public void Save()
        {
            xmlDocument = new XmlDocument();
            XmlNode rootNode = xmlDocument.CreateElement("NUnitGridRunner");
            XmlNode computersNode = xmlDocument.CreateElement("Computers");
            xmlDocument.AppendChild(rootNode);
            rootNode.AppendChild(computersNode);

            foreach (KeyValuePair<string, string> pair in nameMap)
            {
                XmlNode computerNode = xmlDocument.CreateElement("Computer");
                XmlNode nameNode = xmlDocument.CreateElement("Name");
                XmlNode nickNameNode = xmlDocument.CreateElement("NickName");

                nameNode.InnerText = pair.Key;
                nickNameNode.InnerText = pair.Value;

                computersNode.AppendChild(computerNode);
                computerNode.AppendChild(nameNode);
                computerNode.AppendChild(nickNameNode);
            }

            xmlDocument.Save(nameMappingFile);
        }
    }
}